<?php
namespace \Pinenut;

/**
 * 
 * Класс с базовым интерфейсом для кеширования
 * Предполагается, что он должен наследоваться реализациями 
 * для конкретного хранилища (APC, memcached)
 * 
 * Ключевые моменты реализации:
 * 1) пакетные операции
 * 2) инвалидация по тэгам
 * 3) поддержка "грязных данных" как по времени жизни, так и по тэгам
 * 4) для "грязных" записей - проверка на блокировку (опционально) 
 * 5) для ненайденных записей проверка на блокировку и установка в случае её отсутствия (опционально)
 * 6) локальная буферизация данных
 * 
 * Для реализации всех этих извращений придётся ввести объект кеширования, 
 * у которого, помимо собственно данных, будет идти еще набор служебных свойств
 * таких как тэги, время жизни, признак "грязности"
 * 
 * TODO: Хотелось бы реализовать так же стратегию прямого сброса кеша (по тем же тэгам)
 * эта схема нужна для оптимизации анонимной части сайта - кеширование анонимных запросов
 * на фронтэнде в memcached (модуль для nginx). Для этого придётся хранить списки ключей
 * для каждого тэга. Видимо будет отдельный абстрактный класс
 * 
 * 
 * @author kosh
 *
 */

abstract class Cache {
	/**
	 * Получаем записи из хранилища
	 * 
	 * этапы работы:
	 * 
	 * 1) запрашиваем массив данных из кеш
	 * 2) прокисшие по времени записи пачкаем
	 * 3) вытаскиваем из чистых записей тэги в единый список
	 * 4) запрашиваем версии тэгов
	 * 5) пачкаем чистые записи протухшими тэгам
	 * 6) если $checkDirtyLock или $missLock - составляем массив грязных и не найденных записей
	 * 7) если $checkDirtyLock, проверяем какие из них залочены - пишем в объект ответа
	 * 8) если $missLock, пробуем залочить все грязные и не найденные, если удаётся - пишем в объект ответа
	 * 
	 * что-то не так, надо определиться со стратегией проверки и блокировки грязных...
	 * 
	 * У нас планируется два основных типа запросов к кеш
	 * 1) запросы карты прав доступа - блокировать карту не нужно т.к. модификация будет после перестроения, 
	 * 		грязные данные не факт что нужны, надо подумать
	 * 2) запросы на получение блоков данных - нужно блокировать на перестроение если не найдено, 
	 * 		если найдены грязные, то в случае если запрашиваем только чистые, блокируем и их
	 * 
	 * @param array|string $keys - один ключ или массив ключей
	 * @param bool $checkDirtyLock - проверять грязные данные на блокировку
	 * @param bool $missLock - устанавливать блокировку, если запись не найдена и блокировки не стояло
	 * @param bool $dirtyLock - устанавливать блокировку, если запись не найдена и блокировки не стояло
	 * @return multitype:\Pinenut\Cache\Item 
	 */
	public function get($keys, $checkDirtyLock = false, $missLock = false, $dirtyLock = false) {
		return array(new \Pinenut\Cache\Item(), new \Pinenut\Cache\Item(), new \Pinenut\Cache\Item(),);
	}
}